using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace PddWebAuto.Helper
{
    public class WebHelper
    {
        public static async Task<string> HttpPostAsync(string url, Dictionary<string, string> header,
            string data, List<Cookie> cookies = default)
        {
            return await HttpAsync(url, "POST", header, data, cookies);
        }

        public static async Task<string> HttpGetAsync(string url, Dictionary<string, string> header, int timeOut)
        {
            return await HttpAsync(url, "GET", header, default, default, default, timeOut);
        }

        public static async Task<string> HttpAsync(string url, string method, Dictionary<string, string> header,
            string data, List<Cookie> cookies = default, WebProxy proxy = null, int timeOut = -1)
        {
            try
            {
                var cookieContainer = new CookieContainer();
                using (var client = new HttpClient(new HttpClientHandler
                       {
                           AllowAutoRedirect = false,
                           AutomaticDecompression = DecompressionMethods.GZip,
                           UseProxy = proxy != null,
                           Proxy = proxy,
                           CookieContainer = cookieContainer,
                           UseCookies = true
                       }))
                {
                    var req = new HttpRequestMessage(method == "POST" ? HttpMethod.Post : HttpMethod.Get, url);
                    if (timeOut != -1)
                    {
                        client.Timeout = TimeSpan.FromMilliseconds(timeOut);
                    }

                    if (!string.IsNullOrWhiteSpace(data))
                    {
                        req.Content = header.ContainsKey("Content-Type")
                            ? new StringContent(data, Encoding.UTF8, header["Content-Type"])
                            : new StringContent(data, Encoding.UTF8);
                    }

                    if (cookies != null && cookies.Count != 0)
                    {
                        foreach (var cookie in cookies)
                        {
                            cookieContainer.Add(cookie);
                        }
                    }

                    if (header != null && header.Count > 0)
                    {
                        foreach (var item in header)
                        {
                            if (req.Content != null && item.Key == "Content-Type")
                            {
                                continue;
                            }
                            req.Headers.Add(item.Key, item.Value);
                        }
                    }

                    var cancel = Program.CancellationTokenSource != null
                        ? CancellationTokenSource.CreateLinkedTokenSource(Program.CancellationTokenSource.Token)
                        : new CancellationTokenSource();

                    var rsp = await client.SendAsync(req, cancel.Token);
                    if (!rsp.IsSuccessStatusCode)
                    {
                        return string.Empty;
                    }
                    return await rsp.Content.ReadAsStringAsync();
                }
            }
            catch (Exception)
            {
                // ignored
            }

            return string.Empty;
        }

        private static bool ServerCertificateValidationCallback(object sender, X509Certificate certificate,
            X509Chain chain)
        {
            return true;
        }
    }
}